package com.reder.practice.common.util;

import com.reder.practice.bean.LoginInfo;
import com.reder.practice.bean.Manager;
import com.reder.practice.bean.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * 会话工具类
 *
 * @author Fish
 * <p>Email: fishinlove@163.com</p>
 * <p>created by 2019/09/23 14:50:07</p>
 */
public final class SessionUtil {

    // 从 request 中读取登录 token 信息的 key
    // 一个是请求体内的，一个是请求头内的
    private static final String TOKEN_KEY_IN_REQUEST_BODY = "_token";
    private static final String TOKEN_KEY_IN_REQUEST_HEADER = "Authentication";

    // 从 request 中获取登录的用户对象 (User)
    public static User userOf(HttpServletRequest request) {
        return (User) loginObjectOf(request);
    }

    // 从 request 中获取登录的用户对象 (Manager)
    public static Manager managerOf(HttpServletRequest request) {
        return (Manager) loginObjectOf(request);
    }

    // 从 request 中获取登录的用户对象
    public static Object loginObjectOf(HttpServletRequest request) {

        // 优先从请求头中获取 Auth 认证信息，如果获取不到再从请求体中获取
        String tokenInHeader = request.getHeader(TOKEN_KEY_IN_REQUEST_HEADER);
        if (!CodeUtil.isBlank(tokenInHeader)) {
            return request.getSession().getAttribute(tokenInHeader);
        }

        // 请求头中没有认证信息，从请求体中获取
        String tokenInBody = request.getParameter(TOKEN_KEY_IN_REQUEST_BODY);
        return request.getSession().getAttribute(tokenInBody);
    }

    // 判断是否登录
    public static boolean hasLogin(HttpServletRequest request) {
        return loginObjectOf(request) != null;
    }

    // 生成这个用户的验证 token
    public static String tokenOf(User user) {

        // 原本是使用随机生成的，由于 session 是不会过期的，
        // 所以这边有可能会导致 token 堆积,所以改为用户信息指纹提取的方式，
        // 这样生成的 token 和用户信息有关，重新登录可以复用 token
        return CodeUtil.md5(String.valueOf(user.getId())) + user.getId() +
                CodeUtil.md5(user.getNickName());
    }

    // 将登录信息保存到 session 中
    public static void putLoginInfoToSession(LoginInfo loginInfo, HttpSession session) {
        session.setAttribute(loginInfo.getToken(), loginInfo.getUser());
    }
}
